#include "./socket_lib/ServerSocket.h"
#include "./socket_lib/SocketException.h"
#include "./CommFormat.h"
#include <iostream>
#include <string>
#include <string.h>

using namespace std;

int main (void)
{
	std::cout << "running....\n";

	try
	{
		/* Create the socket */
		//ServerSocket server ( 2000 );
		struct sockaddr_in6 m_addr;
		int m_sock;
		memset ( &m_addr, 0, sizeof ( m_addr ) );
		m_sock = socket ( AF_INET6, SOCK_STREAM, 0 );

		//TIME_WAIT - argh
		int on = 1;
		if ( setsockopt ( m_sock, SOL_SOCKET, SO_REUSEADDR, ( const char* ) &on, sizeof ( on ) ) == -1 )
		{
			return false;
		}

		m_addr.sin6_family = AF_INET6;
		m_addr.sin6_addr = in6addr_any;
		m_addr.sin6_port = htons ( 2000 );

		int bind_return = ::bind ( m_sock, ( struct sockaddr * ) &m_addr, sizeof ( m_addr ) );
		if ( bind_return == -1 )
		{
			return false;
		}

		int listen_return = listen ( m_sock, MAXCONNECTIONS );

		if ( listen_return == -1 )
		{
			return false;
		}

		int addr_length = sizeof ( m_addr );

		struct VlinkStateInfo v1;
		v1.vlink_no = 2;
		v1.status = 1;
		v1.req_hop_num = 10;
		v1.res_hop_num = 11;
		v1.rrt = 4;
		/*
		v1.peer_addr.__u6_addr8[0] = 1;
		v1.peer_addr.__u6_addr8[1] = 1;
		v1.peer_addr.__u6_addr8[2] = 1;
		v1.peer_addr.__u6_addr8[3] = 1;
		v1.peer_addr.__u6_addr8[4] = 1;
		v1.peer_addr.__u6_addr8[5] = 1;
		v1.peer_addr.__u6_addr8[6] = 1;
		v1.peer_addr.__u6_addr8[7] = 1;
		v1.peer_addr.__u6_addr8[8] = 1;
		v1.peer_addr.__u6_addr8[9] = 1;
		v1.peer_addr.__u6_addr8[10] = 1;
		v1.peer_addr.__u6_addr8[11] = 1;
		v1.peer_addr.__u6_addr8[12] = 1;
		v1.peer_addr.__u6_addr8[13] = 1;
		v1.peer_addr.__u6_addr8[14] = 1;
		v1.peer_addr.__u6_addr8[15] = 1;
		*/
		v1.local_vlink_addr = 0xcccccccc;
		v1.peer_vlink_addr = 0xcccccccc;
		v1.hello_interval = 20;
		struct VlinkInfoMsg msg;
		msg.type = 3;
		msg.arr_len = 1;
		msg.vlink_num = 3;
		msg.stat_info[0] = v1;
		string data((char*)&msg, 27);
		char buff[256];

		while ( true )
		{
			int fd = accept ( m_sock, ( sockaddr * ) &m_addr, ( socklen_t * ) &addr_length );
			cout << "new sock came." << endl;

			try
			{
				read ( fd, buff, 256 );
				cout << "sending..." << endl;
				for ( int i = 0; i < 10; i++ )
				{
					write ( fd, (char*)&msg, 27 );
				}
			}
			catch ( SocketException& ) {}

		}
	}
	catch ( SocketException& e )
	{
		std::cout << "Exception was caught:" << e.description() << "\nExiting.\n";
	}

	return 0;
}

